package compiler

import (
	"fmt"
	"strings"
	"kumachan/standalone/util/richtext"
	"kumachan/lang/source"
	"kumachan/lang/textual/ast"
	"kumachan/lang/textual/syntax"
	"kumachan/lang/textual/parser"
	"kumachan/lang/textual/transformer"
	"kumachan/interpreter/program"
)


const PlainSourceCodeSuffix = ".km"
var loaders = [] Loader { plainSourceFileLoader }

func Load(path string, fs FileSystem) (*ast.Root, richtext.Error) {
	var key = MakeFileKey(path, fs)
	for _, l := range loaders {
		if strings.HasSuffix(path, l.Suffix) {
			var content, err = ReadFile(path, fs)
			if err != nil { return nil, richtext.ErrorFrom(err) }
			return l.Load(content, key)
		}
	}
	var err = fmt.Errorf("no loader available for file \"%s\"", key)
	return nil, richtext.ErrorFrom(err)
}
func Builtin() (string, FileSystem) {
	var name = program.BuiltinFileName()
	var fs = EmbeddedFileSystem {
		Id: "builtin",
		FS: program.BuiltinFileSystem(),
	}
	return name, fs
}

var plainSourceFileLoader = Loader {
	Suffix: PlainSourceCodeSuffix,
	Load:   func(content ([] byte), key source.FileKey) (*ast.Root, richtext.Error) {
		var code = source.DecodeUtf8ToCode(content)
		var name = key.String()
		var root = syntax.DefaultRootPartName
		var cst, err = parser.Parse(code, root, name)
		if err != nil { return nil, err }
		var ast = transformer.Transform(cst, key).(ast.Root)
		return &ast, nil
	},
}


type Loader struct {
	Suffix  string
	Load    func(bytes ([] byte), key source.FileKey) (*ast.Root, richtext.Error)
}
type PathDesc string
func MakeFileKey(path string, fs FileSystem) source.FileKey {
	return source.FileKey {
		Context: fs.Key(),
		Path:    path,
	}
}


